// 加载 modules 模块
var http = require('http');
var express = require('express');
var app = express();
var server = http.Server(app);
var io = require('socket.io')(server);

// 加载 Demo
app.use(express.static('demo'));
app.get('/teacher', function(req, res) {
    res.sendFile(__dirname + "/demo/" + "index.html");
});
app.get('/student', function(req, res) {
    res.sendFile(__dirname + "/demo/" + "student.html");
});
app.get('/replay', function(req, res) {
    res.sendFile(__dirname + "/demo/" + "replay.html");
});

// 加载 local 模块
require('./helper/string.js');
var config = require('./config');
var common = require('./helper/common');

// 获取配置参数
var port = process.env.PORT || config.PORT;
var version = config.VERSION;

// 记录客户端集合
var clients = new Map();
// 记录用户集合
var users = new Map();

var resolveSocketId = function(socketid) {
    return socketid.split('/#').join('');
};

/**
 * 检测对象有效性
 */
var isValidObject = function(obj) {
    if (typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length) {
        return true;
    } else {
        return false;
    }
};

/**
 * 检测用户数据
 * @param pid [用户Id]
 * @param pname [用户姓名]
 */
var checkUserData = function(data) {
    if (isValidObject(data)) {
        if (data.hasOwnProperty('uid')) {
            return false;
        }
        if (data.hasOwnProperty('pid') && data.hasOwnProperty('pname')) {
            return true;
        }
    }
    return false;
};

/**
 * 客户端上线
 */
io.on('connection', function(socket) {
    var token = resolveSocketId(socket.id);
    clients.set(token, socket);
    console.log('A user [%s] connection.', token);
    socket.emit('connectSuccess', { 'token': token });

    /**
     * 用户上线
     * @param data [用户对象]
     * @return data [用户对象]
     */
    socket.on('userSignin', function(data) {
        if (checkUserData(data) == false) {
            console.log('Invalid user object.');
            return false;
        }
        // console.log('A user signin:' + JSON.stringify(data));
        var room = data.room || 'default';
        data.room = room;
        data.uid = token;
        socket.join(room);
        users.set(token, data);
        // 向房间内其他用户广播新用户上线
        socket.to(room).emit('userSigninSuccess', data);
    });

    /**
     * 获取房间内用户列表
     * @param room [房间]
     * @return usersArr [用户对象]
     */
    socket.on('getUsersList', function(room) {
        room = room || 'default';
        var usersArr = [];
        users.forEach(function(value, key, map) {
            if (value.room == room) {
                usersArr.push(value);
            }
        });
        socket.emit('usersList', usersArr);
        // console.log('usersList:' + JSON.stringify(usersArr));
    });

    /**
     * 发送消息
     * @param content [必填，消息内容]
     * @param to [指定接收人，多个用户之间用','分隔]
     * @param hasMe [是否包含自己，默认包含自己]
     * @return msg [消息对象]
     */
    socket.on('sendChatMsg', function(data) {
        if (!isValidObject(data)) {
            console.log('Invalid chat object.');
            return false;
        }
        if (!data.hasOwnProperty('content') || data.content == '') {
            console.log('Chat content is empty.');
            return false;
        }

        var user = users.get(token);
        if (!isValidObject(user)) {
            console.log('Invalid user.');
            return false;
        }
        var room = user.room,
            hasMe = true,
            toIds, client, i;
        data.sender = user;
        data.time = common.now();
        if (!data.hasOwnProperty('to') || data.to == '') {
            toIds = new Array;
        } else {
            toIds = data.to.split(',');
        }
        if (data.hasOwnProperty('hasMe') && data['hasMe'] == false) {
            hasMe = false;
        }

        if (toIds.length > 0) {
            for (i = 0; i < toIds.length; i++) {
                client = clients.get(toIds[i]);
                if (client != null) {
                    client.emit('getChatMsg', data);
                }
            }
        } else {
            if (hasMe) {
                io.sockets.to(room).emit('getChatMsg', data);
            } else {
                socket.to(room).emit('getChatMsg', data);
            }
        }
    });

    /**
     * 客户端下线
     * @return user [用户对象]
     */
    socket.on('disconnect', function() {
        console.log('Client [%s] disconnect:', token);
        var user = users.get(token);
        if (user == null) {
            return;
        }
        socket.leave(user.room);
        //广播用户掉线
        io.sockets.to(user.room).emit('userDisconnect', user);
        users.delete(token);
        clients.delete(token);
    });
});

// 启动服务
server.listen(port, function() {
    console.log('通讯服务 %s', version);
    console.log('Server listening at port %d in %s.', port, common.now());
});